﻿////#define _CRT_SECURE_NO_WARNINGS
////
//////template<class T>
//////class SmartPtr
//////{
//////public:
//////	//RAII
//////	SmartPtr(T* ptr)
//////		:_ptr(ptr)
//////	{}
//////	
//////	~SmartPtr()
//////	{
//////		cout << "delete[] " << _ptr << endl;
//////		delete[] _ptr;
//////	}
//////
//////	T& operator*()
//////	{
//////		return *_ptr;
//////	}
//////	
//////	T* operator->()
//////	{
//////		return _ptr;
//////	}
//////
//////	T& operator[](size_t)
//////	{
//////		return _ptr[i];
//////	}
//////private:
//////	T* _ptr;
//////};
//////
//////double Divide(int a, int b)
//////{
//////	// 当b == 0时抛出异常
//////	if (b == 0)
//////	{
//////		throw "Divide by zero condition!";
//////	}
//////	else
//////	{
//////		return (double)a / (double)b;
//////	}
//////}
//////
//////void Func()
//////{	
//////	SmartPtr<int> sp1 = new int[10];
//////	SmartPtr<int> sp2 = new int[10];
//////}
////
////
//////struct Date
//////{
//////	int _year;
//////	int _month;
//////	int _day;
//////	Date(int year = 1, int month = 1, int day = 1)
//////		:_year(year)
//////
//////		, _month(month)
//////		, _day(day)
//////	{}
//////	~Date()
//////	{
//////		cout << "~Date()" << endl;
//////	}
//////};
//////
//////int main()
//////{
//////	auto_ptr<Date> ap1(new Date);
//////	// 拷⻉时，管理权限转移，被拷⻉对象ap1悬空
//////	auto_ptr<Date> ap2(ap1);
//////	// 空指针访问，ap1对象已经悬空
//////	//ap1->_year++;
//////	unique_ptr<Date> up1(new Date);
//////	// 不⽀持拷⻉
//////	//unique_ptr<Date> up2(up1);
//////	// ⽀持移动，但是移动后up1也悬空，所以使⽤移动要谨慎
//////	unique_ptr<Date> up3(move(up1));
//////	shared_ptr<Date> sp1(new Date);
//////	// ⽀持拷⻉
//////	shared_ptr<Date> sp2(sp1);
//////	shared_ptr<Date> sp3(sp2);
//////	cout << sp1.use_count() << endl;
//////	sp1->_year++;
//////	cout << sp1->_year << endl;
//////	cout << sp2->_year << endl;
//////	cout << sp3->_year << endl;
//////	// ⽀持移动，但是移动后sp1也悬空，所以使⽤移动要谨慎
//////	shared_ptr<Date> sp4(move(sp1));
//////	return 0;
//////}
////
////#include<iostream>
////using namespace std;
////
////struct Date
////{
////	int _year;
////	int _month;
////	int _day;
////	Date(int year = 1, int month = 1, int day = 1)
////		:_year(year)
////
////		, _month(month)
////		, _day(day)
////	{}
////	~Date()
////	{
////		cout << "~Date()" << endl;
////	}
////};
////
////template<class T>
////void DeleteArrayFunc(T* ptr)
////{
////	delete[] ptr;
////}
////
////template<class T>
////class DeleteArray
////{
////public:
////	void operator()(T* ptr)
////	{
////		delete[] ptr;
////	}
////};
////
////class Fclose
////{
////public:
////	void operator()(FILE* ptr)
////	{
////		cout << "fclose:" << ptr << endl;
////		fclose(ptr);
////	}
////};
////
////int main()
////{
////	// 这样实现程序会崩溃
////	 //unique_ptr<Date> up1(new Date[10]);
////	 //shared_ptr<Date> sp1(new Date[10]);
////	// 解决⽅案1
////	// 因为new[]经常使⽤，所以unique_ptr和shared_ptr
////	// 实现了⼀个特化版本，这个特化版本析构时⽤的delete[]
////	unique_ptr<Date[]> up1(new Date[5]);
////	shared_ptr<Date[]> sp1(new Date[5]);
////	// 解决⽅案2
////	// 仿函数对象做删除器
////	//unique_ptr<Date, DeleteArray<Date>> up2(new Date[5], DeleteArray<Date>());
////	// unique_ptr和shared_ptr⽀持删除器的⽅式有所不同
////	// unique_ptr是在类模板参数⽀持的，shared_ptr是构造函数参数⽀持的
////	// 这⾥没有使⽤相同的⽅式还是挺坑的
////	// 使⽤仿函数unique_ptr可以不在构造函数传递，因为仿函数类型构造的对象直接就可以调⽤
////	// 但是下⾯的函数指针和lambda的类型不可以
////	unique_ptr<Date, DeleteArray<Date>> up2(new Date[5]);
////	shared_ptr<Date> sp2(new Date[5], DeleteArray<Date>());
////
////	// 函数指针做删除器
////	unique_ptr<Date, void(*)(Date*)> up3(new Date[5], DeleteArrayFunc<Date>);
////	shared_ptr<Date> sp3(new Date[5], DeleteArrayFunc<Date>);
////	// lambda表达式做删除器
////	auto delArrOBJ = [](Date* ptr) {delete[] ptr; };
////	unique_ptr<Date, decltype(delArrOBJ)> up4(new Date[5], delArrOBJ);
////	shared_ptr<Date> sp4(new Date[5], delArrOBJ);
////	// 实现其他资源管理的删除器
////	shared_ptr<FILE> sp5(fopen("Test.cpp", "r"), Fclose());
////	shared_ptr<FILE> sp6(fopen("Test.cpp", "r"), [](FILE* ptr) {
////		cout << "fclose:" << ptr << endl;
////		fclose(ptr);
////		});
////	return 0;
////}
//
#include<iostream>
#include<functional>
using namespace std;
struct Date
{
	int _year;
	int _month;
	int _day;
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}
	~Date()
	{
		cout << "~Date()" << endl;
	}
};

namespace bit
{
	template<class T>
	class auto_ptr
	{
	public:
		auto_ptr(T* ptr)
			:_ptr(ptr)
		{}
		auto_ptr(auto_ptr<T>& sp)
			:_ptr(sp._ptr)
		{
			//管理权转移
			sp._ptr = nullptr;
		}
		auto_ptr<T>& operator=(auto_ptr<T>& ap)
		{
			//检查是否为自己给自己赋值
			if (this != &ap)
			{
				if (_ptr)
					delete _ptr;
				//转移ap中资源到当前对象中
				_ptr = ap._ptr;
				ap._ptr = NULL;
			}
			return *this;
		}
		~auto_ptr()
		{
			if (_ptr)
			{
				std::cout << "delete:" << _ptr << std::endl;
				delete _ptr;
			}
		}
		//像指针一样使用
		T& operator*()
		{
			return *_ptr;
		}
		T* operator->()
		{
			return _ptr;
		}
	private:
		T* _ptr;
	};

	template<class T>
	class unique_ptr
	{
	public:
		explicit unique_ptr(T* ptr)
			:_ptr(ptr)
		{}

		~unique_ptr()
		{
			if (_ptr)
			{
				cout << "delete:" << _ptr << endl;
				delete _ptr;
			}
		}

		//像指针一样使用
		T& operator*()
		{
			return *_ptr;
		}

		T* operator->()
		{
			return _ptr;
		}

		unique_ptr(const unique_ptr<T>& sp) = delete;
		unique_ptr<T>& operator=(const unique_ptr<T>& sp) = delete;
		unique_ptr(unique_ptr<T>&& sp)
			:_ptr(sp._ptr)
		{
			sp._ptr = nullptr;
		}

		unique_ptr<T>& operator=(unique_ptr<T>&& sp)
		{
			delete _ptr;
			_ptr = sp._ptr;
			sp._ptr = nullptr;
		}

	private:
		T* _ptr;
	};


	template<class T>
	class shared_ptr
	{
	public:
		explicit shared_ptr(T* ptr = nullptr)
			:_ptr(ptr)
			, _pcount(new int(1))
		{}

		template<class D>
		shared_ptr(T* ptr, D del)
			: _ptr(ptr)
			, _pcount(new int(1))
			, _del(del)
		{}

		shared_ptr(const shared_ptr<T>& sp)
			:_ptr(sp._ptr)
			, _pcount(sp._pcount)
			, _del(sp._del)
		{
			++(*_pcount);
		}

		void release()
		{
			if (--(*_pcount) == 0)
			{
				// 最后⼀个管理的对象，释放资源
				_del(_ptr);
				delete _pcount;
				_ptr = nullptr;
				_pcount = nullptr;
			}
		}

		shared_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			if (_ptr != sp._ptr)
			{
				release();
				_ptr = sp._ptr;
				_pcount = sp._pcount;
				++(*_pcount);
				_del = sp._del;
			}
			return *this;
		}

		T* get() const
		{
			return _ptr;
		}

		int use_count() const
		{
			return *_pcount;
		}
		T& operator*()
		{
			return *_ptr;
		}
		T* operator->()
		{
			return _ptr;
		}

	private:
		T* _ptr;
		int* _pcount;
		//atomic<int>* _pcount;
		function<void(T*)> _del = [](T* ptr) {delete ptr; };
	};


	template<class T>
	class weak_ptr
	{
	public:
		weak_ptr()
		{}
		weak_ptr(const shared_ptr<T>& sp)
			:_ptr(sp.get())
		{}
		weak_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			_ptr = sp.get();
			return *this;
		}
	private:
		T* _ptr = nullptr;
	};

	template<class T>
	class weak_ptr
	{
	public:
		weak_ptr()
		{}
		weak_ptr(const shared_ptr<T>& sp)
			:_ptr(sp.get())
		{}
		weak_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			_ptr = sp.get();
			return *this;
		}
	private:
		T* _ptr = nullptr;
	};
}
int main()
{
	Date *d1 = new Date[5];

	//bit::auto_ptr<Date> ap1(new Date);
	//// 拷⻉时，管理权限转移，被拷⻉对象ap1悬空
	//bit::auto_ptr<Date> ap2(ap1);
	//// 空指针访问，ap1对象已经悬空
	////ap1->_year++;

	//bit::unique_ptr<Date> up1(new Date);
	//// 不⽀持拷⻉
	////unique_ptr<Date> up2(up1);
	//// ⽀持移动，但是移动后up1也悬空，所以使⽤移动要谨慎
	//bit::unique_ptr<Date> up3(move(up1));
	//bit::shared_ptr<Date> sp1(new Date);
	//// ⽀持拷⻉
	//bit::shared_ptr<Date> sp2(sp1);
	//bit::shared_ptr<Date> sp3(sp2);
	//cout << sp1.use_count() << endl;
	//cout << sp2.use_count() << endl;
	//cout << sp3.use_count() << endl;

	//sp1->_year++;
	//cout << sp1->_year << endl;
	//cout << sp2->_year << endl;
	//cout << sp3->_year << endl;
	//return 0;
}

//#include <iostream>
//#include <memory>
//
//class Base {
//public:
//    virtual void print1() {
//        std::cout << "Base" << std::endl;
//    }
//
//    virtual void print2() {
//        std::cout << "Base" << std::endl;
//    }
//    virtual ~Base() {}
//};
//
//class Derived : public Base {
//public:
//    void print1() override {
//        std::cout << "Derived1" << std::endl;
//    }
//    void print2() override {
//        std::cout << "Derived2" << std::endl;
//    }
//};
//
//int main() {
//    // 普通指针可以隐式转换
//    Derived* derivedRawPtr = new Derived();
//    Base* baseRawPtr = derivedRawPtr;
//
//    // std::unique_ptr 不支持隐式转换
//    std::unique_ptr<Derived> derivedUniquePtr = std::make_unique<Derived>();
//    // 下面这行代码会编译错误
//    // std::unique_ptr<Base> baseUniquePtr = derivedUniquePtr; 
//
//    // 必须使用 std::move 显式转移所有权
//    std::unique_ptr<Base> baseUniquePtr = std::move(derivedUniquePtr);
//    if (derivedUniquePtr == nullptr) {
//        baseUniquePtr->print1();
//        baseUniquePtr->print2();
//        std::cout << "derivedUniquePtr is null after move." << std::endl;
//    }
//    baseUniquePtr->print1();
//
//    delete derivedRawPtr; // 释放普通指针分配的内存
//    return 0;
//}